package org.xielei.stream;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.xielei.util.JsonUtil;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author xielei
 */
public class OptionalTest {

    @Test
    public void optionalTest() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DAY_OF_MONTH, 0);
        Date time = calendar.getTime();
        System.out.println(time);

        JSONObject jsonObject = JSONObject.parseObject("{\"docCode\": \"001038\", \"docName\": \"王晓丽\", \"deptCode\": \"6012\", \"deptName\": \"方便门诊\", \"itemList\": [{\"num\": \"1.0\", \"name\": \"六味地黄丸\", \"spec\": \"200丸\", \"unit\": \"瓶\", \"execDeptName\": null}], \"windowsNoList\": [\"[{\\\"clinicCode\\\":\\\"599984508\\\",\\\"deptName\\\":\\\"门诊药房\\\",\\\"drugName\\\":\\\"发药窗口5\\\"}]\", \"[{\\\"clinicCode\\\":\\\"599984508\\\",\\\"deptName\\\":\\\"门诊药房\\\",\\\"drugName\\\":\\\"发药窗口5\\\"}]\"]}");
//        JSONObject jsonObject = JSONObject.parseObject("{\"docCode\": \"999023\", \"docName\": \"测试医生3\", \"deptCode\": \"6011\", \"deptName\": \"营养科门诊\", \"itemList\": [{\"num\": \"6.0\", \"name\": \"M板蓝根(1:6.00)\", \"spec\": \"1:6.00\", \"unit\": \"克\", \"execDeptName\": null}], \"windowsNoList\": [\"[{\\\"clinicCode\\\":\\\"34637229\\\",\\\"deptName\\\":\\\"门诊药房\\\",\\\"drugName\\\":\\\"非草药请到2号窗口(10号窗口)\\\",\\\"recipeNoList\\\":[\\\"1111431865\\\",\\\"1111431035\\\",\\\"1111400852\\\",\\\"1111431936\\\"]},{\\\"clinicCode\\\":\\\"34673084\\\",\\\"deptName\\\":\\\"门诊药房\\\",\\\"drugName\\\":\\\"非草药请到2号窗口(草药请到16窗口)\\\",\\\"recipeNoList\\\":[\\\"1111577133\\\",\\\"1111576571\\\",\\\"1111576573\\\",\\\"1111576338\\\",\\\"1111576437\\\"]}]\"]}");
        System.out.println("json----> " + jsonObject);

        List<String> objects = (List<String>) jsonObject.get("windowsNoList");
        System.out.println("objects---> " + objects.toString());

        Object drugName1 = JsonUtil.readList(objects.get(0), WindowsNo.class);
        System.out.println("windowsNos---> " + drugName1);


        String drugName = Optional.ofNullable((List<String>) jsonObject.get("windowsNoList"))
                .filter(CollectionUtils::isNotEmpty)
                .map(windows -> windows.stream()
                        .filter(StringUtils::isNotBlank)
                        .map(s -> JsonUtil.readList(s, WindowsNo.class))
                        .map(list -> (List<WindowsNo>) list)
                        .map(l -> l.stream()
                                .map(WindowsNo::getDrugName)
                                .collect(Collectors.joining(",")))
                        .collect(Collectors.joining(",", "-", ""))
                ).orElse("");

        System.out.println("drugName>>>>>> " + drugName);
    }

    @Test
    public void optionalOfNullable() {
        String value = null;
        int remindDays = Optional.ofNullable(value)
                .map(Integer::parseInt)
                .orElse(Integer.parseInt("3"));
        System.out.println(remindDays);

        BigDecimal a = BigDecimal.TEN;
        System.out.println(Optional.ofNullable(a)
                .orElse(BigDecimal.ONE));

        Map<String, Object> addInfo = new HashMap<>(2);
//        Map<String, Object> addInfo = null;
        System.out.println(addInfo);
        String batchNo = Optional.ofNullable(addInfo)
                .map(stringObjectMap -> stringObjectMap.get("batchNo"))
                .map(String::valueOf)
                .orElse("");
        System.out.println("batch:" + batchNo);
    }

    @Test
    public void optionalOfNullTest() {

        Model model = new Model();
        System.out.println("model.getParam().toString() " + model.getParam().toString());
        System.out.println("model.getParam().isEmpty() " + model.getParam().isEmpty());

        @SuppressWarnings("unchecked")
        List<String> inspectTypeList =
                (List<String>) Optional.ofNullable(model.getParam())
                        .filter(stringObjectMap -> {
                            System.out.println("stringObjectMap.toString() " + stringObjectMap.toString());
                            System.out.println("map.size: " + stringObjectMap.size());
                            return stringObjectMap.size() > 0;
                        })
                        .orElseGet(() -> {
                            Map<String, Object> map = new HashMap<>(2);
                            map.put("inspectType", new ArrayList<>());
                            System.out.println("in orElseGet, map: " + map.toString());
                            return map;
                        })
                        .get("inspectType");

        System.out.println("inspectTypeList.isEmpty() " + inspectTypeList.isEmpty());
        System.out.println("inspectTypeList.toString() " + inspectTypeList.toString());

        if (inspectTypeList.isEmpty()) {
            inspectTypeList.add("001");
            inspectTypeList.add("002");
            inspectTypeList.add("003");
        }

        inspectTypeList.forEach(System.out::println);
    }

    @Test
    public void ofNullable() {
        List<String> array = Arrays.asList("1234", "312");
        String windowsNum = Optional.ofNullable(array)
                .filter(collection -> !CollectionUtils.isEmpty(collection))
                .map(windows -> "-" + String.join(",", windows))
                .orElse("");
        System.out.println(">>>>>>>" + windowsNum);

        List<String> idList = Arrays.asList("1|2", "2|3", "3", "4");

        String deptCode = "1|2";
        String[] deptCodeArray = deptCode.split("\\|");
        for (String s : deptCodeArray) {
            System.out.println(s);
        }
        List<String> deptCodeList = Stream.of(deptCodeArray).collect(Collectors.toList());
        System.out.println(deptCodeList.toString());
        System.out.println(deptCodeList.get(0));
        System.out.println(deptCodeList.get(1));

        boolean b = idList.stream()
                .anyMatch(a -> a.contains("|"));
        System.out.println(b);
    }

    @Test
    public void nullTest() {
        Model model = new Model();
        String deptCode = Optional.ofNullable(model.getParam()).filter(MapUtils::isNotEmpty).map(a -> a.get("deptCode")).map(String::valueOf).orElse("empty");
        List<String> arr = Optional.ofNullable(model.getParam()).filter(MapUtils::isNotEmpty).map(a -> (List<String>) a.get("deptCode")).orElse(new ArrayList<>());
        System.out.println(deptCode);
        System.out.println("arr>>> " + arr);
    }

    @Getter
    @Setter
    static class Model {
        private Map<String, Object> param = null;
//        private Map<String, Object> param;

//        Model() {
//            this.param.put("inspectType", Arrays.asList("0001", "0002"));
//        }
    }

    @Getter
    @Setter
    @ToString
    @NoArgsConstructor
    @AllArgsConstructor
    private static class WindowsNo {
        private String clinicCode;

        private String deptName;

        private String drugName;

        private List<String> recipeNoList;
    }

}
